﻿using System;
using System.Collections.Generic;
using System.Text;

namespace dllLink
{
    // Classe des estimateurs empiriques
    // pour les rendements et la matrice de variance-covariance
    internal class EmpiricalEstimator : VarCovarEstimator
    {

        public EmpiricalEstimator(Product theProduct, DateTime thePricingDate, TimeSpan theHistoryDepth)
        {
            mvProduct = theProduct;
            mvPricingDate = thePricingDate;
            mvHistoryDepth = theHistoryDepth;
        }

        internal override double mComputeMean(double[] data)
        {
            return GSLFunctions.mean(data, 1, data.Length);
        }

        public override double[] mComputeReturn()
        {
            int nbAssets = mvProduct.mGetNbAssets();
            double[] myReturns = new double[nbAssets];
            double[] myData;
            string myName;
            for (int i = 0; i < nbAssets; i++)
            {
                myName = mvProduct.mGetAssetName(i);
                myData = Cotation(myName, mvPricingDate, mvHistoryDepth);
                myReturns[i] = mComputeMean(myData);
            }
            return myReturns;
        }

        internal override double mComputeCov(double[] data1, double[] data2)
        {
            int nbValues = data1.Length;
            int stride = 1;
            double cov = GSLFunctions.covariance(data1, data2, stride, nbValues);
            return cov;
        }

        public override double[,] mComputeMatCov()
        {
            int nbAssets = mvProduct.mGetNbAssets();
            double[,] CovMatrix = new double[nbAssets, nbAssets];
            double[,] data;
            double[] data1;
            double[] data2;
            string Name1, Name2;

            int i, j;
            for (i = 0; i < nbAssets; i++)
            {
                Name1 = mvProduct.mGetAssetName(i);
                data = ReturnsAtSameDates(Name1, Name1, mvPricingDate, mvHistoryDepth);
                data1 = GetUnderlyingData(data, 0);
                CovMatrix[i, i] = mComputeCov(data1, data1);

                for (j = i + 1; j < nbAssets; j++)
                {
                    Name2 = mvProduct.mGetAssetName(j);
                    data = ReturnsAtSameDates(Name1, Name2,mvPricingDate, mvHistoryDepth);
                    data1 = GetUnderlyingData(data, 0);
                    data2 = GetUnderlyingData(data, 1);
                    CovMatrix[i, j] = mComputeCov(data1, data2);
                    CovMatrix[j, i] = CovMatrix[i, j];
                }
            }
            return CovMatrix;
        }


    }
}

